package br.ufal.tci.nexos.arcolive.beans;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.io.IOException;
import java.io.Serializable;

import javax.media.CannotRealizeException;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.EndOfMediaEvent;
import javax.media.MediaLocator;
import javax.media.NoDataSourceException;
import javax.media.NoPlayerException;
import javax.media.RealizeCompleteEvent;
import javax.media.protocol.DataSource;
import javax.media.rtp.ReceptionStats;
import javax.swing.JInternalFrame;

/**
 * LVSPlayerInternalFrame.java
 * 
 * <p>
 * This class is a coupling to LVSPlayer class.
 * </p>
 * 
 * 
 * @author <a href="mailto:felipe@labpesquisas.tci.ufal.br">Felipe Barros Pontes</a>.
 * @author <a href="mailto:leandro@labpesquisas.tci.ufal.br">Leandro Melo de
 *         Sales</a>.
 * @since 0.1
 * @version 0.1
 * 
 * <p>
 * <b>Revisions:</b>
 * 
 * <p>
 * <b>20050317 leandro e felipe</b>
 * <ul>
 * <li> First version
 * </ul>
 */

public class PlayerInternalFrame extends JInternalFrame implements
		ControllerListener, Serializable, NetworkPlayerListener {

	private NetworkPlayer arcoliveNetworkPlayer;

	private MediaLocator mediaLocator;

	private Component videoComponent, controlComponent;

	private int transmissionPort = 40000;

	private int receptionPort = 40020;
	
	private int bufferLength = 400;

	private ReceptionStats receptionStats;

	private String receptorHost = "192.168.7.55";

	private String senderHost = "192.168.7.55";

	private String videoFormatType = null;

	private String audioFormatType = null;

	/**
	 * 
	 */
	public PlayerInternalFrame() {
		super();
		initGUI();
		this.arcoliveNetworkPlayer = new NetworkPlayer();
	}

	/**
	 * @param mediaLocator
	 */
	public void setMediaLocator(MediaLocator mediaLocator) {
		this.mediaLocator = mediaLocator;
		this.arcoliveNetworkPlayer.setMediaLocator(mediaLocator);
	}

	/**
	 * @return
	 */
	public MediaLocator getMediaLocator() {
		return this.mediaLocator;
	}

	/**
	 * @return
	 */
	public int getBufferLength() {
		return this.bufferLength;
	}

	/**
	 * @param bufferLength
	 */
	public void setBufferLength(int bufferLength) {
		this.bufferLength = bufferLength;
	}

	/**
	 * @param playerType
	 */
	public void setPlayerType(String playerType) {
		this.arcoliveNetworkPlayer.setPlayerType(playerType);
	}

	/**
	 * @return
	 */
	public String getPlayerType() {
		return this.arcoliveNetworkPlayer.getPlayerType();
	}

	/**
	 * @return
	 */
	public String getAudioFormatType() {
		return audioFormatType;
	}

	/**
	 * @param audioFormatType
	 */
	public void setAudioFormatType(String audioFormatType) {
		this.audioFormatType = audioFormatType;
		this.arcoliveNetworkPlayer.setAudioFormatType(audioFormatType);
	}

	/**
	 * @return
	 */
	public String getVideoFormatType() {
		return videoFormatType;
	}

	/**
	 * @param videoFormatType
	 */
	public void setVideoFormatType(String videoFormatType) {
		this.videoFormatType = videoFormatType;
		this.arcoliveNetworkPlayer.setVideoFormatType(videoFormatType);
	}

	/**
	 * @return
	 */
	public String getReceptorHost() {
		return receptorHost;
	}

	/**
	 * @param receptorHost
	 */
	public void setReceptorHost(String receptorHost) {
		this.receptorHost = receptorHost;
		this.arcoliveNetworkPlayer.setReceptorHost(receptorHost);
	}

	/**
	 * @return
	 */
	public String getSenderHost() {
		return senderHost;
	}

	/**
	 * @param senderHost
	 */
	public void setSenderHost(String senderHost) {
		this.senderHost = senderHost;
		this.arcoliveNetworkPlayer.setSenderHost(senderHost);
	}

	/**
	 * @return
	 */
	public int getTransmissionPort() {
		return transmissionPort;
	}

	/**
	 * @param transmissionPort
	 */
	public void setTransmissionPort(int transmissionPort) {
		this.transmissionPort = transmissionPort;
		this.arcoliveNetworkPlayer.setTransmissionPort(transmissionPort);
	}

	/**
	 * @return
	 */
	public int getReceptionPort() {
		return receptionPort;
	}

	/**
	 * @param receptionPort
	 */
	public void setReceptionPort(int receptionPort) {
		this.receptionPort = receptionPort;
		this.arcoliveNetworkPlayer.setReceptionPort(receptionPort);
	}

	/**
	 * @return
	 */
	public ArCoLIVEPlayer getArcolivePlayer() {
		return this.arcoliveNetworkPlayer;
	}

	/**
	 * @param arcolivePlayer
	 */
	public void setArcolivePlayer(ArCoLIVEPlayer arcolivePlayer) {
		this.arcoliveNetworkPlayer = (NetworkPlayer) arcolivePlayer;
	}

	/**
	 * @return
	 */
	public ReceptionStats getReceptionStats() {
		return this.receptionStats;
	}

	/**
	 * @throws CannotPlayStreamException
	 */
	public void playLocalMedia() throws CannotPlayStreamException {
		this.arcoliveNetworkPlayer.play();
		this.arcoliveNetworkPlayer.addControllerListener(this);
	}

	/**
	 * @throws CannotHandleStreamException
	 */
	public void playRemoteMedia() throws CannotHandleStreamException {
		this.arcoliveNetworkPlayer.addArcoliveNetworkPlayerListener(this);
		this.arcoliveNetworkPlayer.handleStream();
	}

	/**
	 * 
	 */
	public void pausePlayer() {
		this.arcoliveNetworkPlayer.pause();
	}

	/**
	 * 
	 */
	public void stopPlayer() {
		this.arcoliveNetworkPlayer.stopPlayer();
	}

	/**
	 * @throws CannotStopTransmissionException
	 */
	public void stopRemoteMedia() throws CannotStopTransmissionException {
		this.arcoliveNetworkPlayer.stopReception();
		this.arcoliveNetworkPlayer.stopTrasmission();
	}

	/**
	 * @throws CannotStopTransmissionException
	 */
	public void stopAll() throws CannotStopTransmissionException {
		this.stopPlayer();
		this.stopRemoteMedia();
	}

	/**
	 * @throws CannotTransmitStreamException
	 */
	public void transmitMedia() throws CannotTransmitStreamException {
		this.arcoliveNetworkPlayer.transmitStream();
	}

	/**
	 * 
	 */
	private void initGUI() {
		setTitle(this.title);
		setIconifiable(true);
		setClosable(true);
		setMaximizable(true);
		setResizable(true);
		getContentPane().setLayout(new BorderLayout());
		setVisible(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.media.ControllerListener#controllerUpdate(javax.media.ControllerEvent)
	 */
	public void controllerUpdate(ControllerEvent event) {
		if (event instanceof RealizeCompleteEvent) {
			this.videoComponent = this.arcoliveNetworkPlayer
					.getControlComponent();
			if (this.videoComponent != null) {
				getContentPane().add(this.videoComponent, BorderLayout.SOUTH);
			}
			this.controlComponent = this.arcoliveNetworkPlayer
					.getVisualComponent();
			if (this.controlComponent != null) {
				getContentPane()
						.add(this.controlComponent, BorderLayout.CENTER);
			}
			validate();
		}

		if (event instanceof EndOfMediaEvent) {
			if (this.arcoliveNetworkPlayer.isRepetitive()) {
				try {
					this.arcoliveNetworkPlayer.play();
				} catch (CannotPlayStreamException e) {
					e.printStackTrace();
				}
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see br.ufal.tci.nexos.arcolive.beans.ArCoLIVENetworkPlayerListener#dataSourceReadyEvent(br.ufal.tci.nexos.arcolive.beans.ArCoLIVENetworkPlayerEvent)
	 */
	public void dataSourceReadyEvent(
			NetworkPlayerEvent arCoLIVENetworkPlayerEvent) {
		DataSource dataSource = ((NetworkPlayer) arCoLIVENetworkPlayerEvent
				.getSource()).getReceiveDataSource();
		if (dataSource != null) {
			this.arcoliveNetworkPlayer.setDataSource(dataSource);
			try {
				this.arcoliveNetworkPlayer.play();
			} catch (CannotPlayStreamException e) {
				e.printStackTrace();
			}
			this.arcoliveNetworkPlayer.addControllerListener(this);
		}
	}

	public void receptionStatsReadyEvent(
			NetworkPlayerEvent arCoLIVENetworkPlayerEvent) {
		this.receptionStats = ((NetworkPlayer) arCoLIVENetworkPlayerEvent
				.getSource()).getReceptionStats();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.Component#getPreferredSize()
	 */
	public Dimension getPreferredSize() {
		int w = 0, h = 0;
		if (this.videoComponent != null) {
			Dimension size = this.videoComponent.getPreferredSize();
			w = size.width;
			h = size.height;
		}
		if (this.controlComponent != null) {
			Dimension size = this.controlComponent.getPreferredSize();
			if (w == 0)
				w = size.width;
			h += size.height;
		}
		if (w < 160)
			w = 160;
		return new Dimension(w, h);
	}

}